package com.pengtu.dao.project;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

import org.apache.commons.lang.StringUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.DateTools.Resolution;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.CachingWrapperFilter;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryWrapperFilter;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;

import com.pengtu.dao.hibernate.HibernateDao;
import com.pengtu.entity.project.ProjectInfo;
import com.pengtu.entity.project.SignUpContract;
import com.pengtu.model.LuceneProjectModel;
import com.pengtu.service.app.AccountManager;
import com.pengtu.service.project.ProjectManager;
import com.pengtu.utils.LabelHelper;

@Repository
public class ProjectInfoDao extends HibernateDao<ProjectInfo, Serializable> {
	private ProjectManager projectManager;
	@Autowired
	public void setProjectManager(ProjectManager projectManager) {
		this.projectManager = projectManager;
	}
	private AccountManager accountManager;
	@Autowired
	public void setAccountManager(AccountManager accountManager) {
		this.accountManager = accountManager;
	}

	public void createIndexByLucene(String index) {
		
		try {
			File fsDir = new File(index+"//project");
			Analyzer analyzer = new IKAnalyzer();
			IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_31,
					analyzer);
			Directory dir = FSDirectory.open(fsDir);
			iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE);// 总是重新创建
			if (IndexWriter.isLocked(dir)) {
				IndexWriter.unlock(dir);
				}
			IndexWriter iw = new IndexWriter(dir, iwc);
			List<ProjectInfo> projectInfoList = super.getAll();
			int size = projectInfoList.size();
			long startTime = new Date().getTime();
			
			//添加到索引里去
			Document doc;
			for (ProjectInfo projectInfo : projectInfoList) {
				String projectId = projectInfo.getId();
				List<SignUpContract> listSign = projectManager.findSignList("projectId",projectId);
				Map<String, TreeSet<String>> pp = new HashMap<String, TreeSet<String>>();//存单位
				Map<String, TreeSet<String>> pper = new HashMap<String, TreeSet<String>>();//存单位负责人
				for(SignUpContract sign : listSign){
					String orgName = accountManager.getOrganization(sign.getOrgCode()).getOrgName();
					String person = sign.getBranchOrgCode().getBurderMan();
					String orgType = sign.getContractKind();
					if(StringUtils.isNotEmpty(orgType)){
					if(!pp.containsKey(orgType)){
						TreeSet<String> li = new TreeSet<String>();
						if(StringUtils.isNotEmpty(person)){
						li.add(orgName);}
						pp.put(orgType,li);
					}else{
						if(StringUtils.isNotEmpty(orgName)){
						pp.get(orgType).add(orgName);
						}
					}
					
					if(!pper.containsKey(orgType)){
						TreeSet<String> lr = new TreeSet<String>();
						if(StringUtils.isNotEmpty(person)){
						lr.add(person);}
						pper.put(orgType,lr);
					}else{
						if(StringUtils.isNotEmpty(person)){
						pper.get(orgType).add(person);
						}
					}
					}
				}
				
				doc = new Document();
				doc.add(new Field("id", projectId, Field.Store.YES,
						Field.Index.ANALYZED));
				doc.add(new Field("projectName", projectInfo.getProjName(), Field.Store.YES,
						Field.Index.ANALYZED));
				
				String attown = "" ;
				String techgrade = "";
				String sociallevel = "";
				String orgName = "";
				String principal = "";
				String supervisorOrg = "";
				String supPrincipal = "";
				String constructOrg ="";
				String conPrincipal = "";
				if(projectInfo.getAtTown()!= null){
					String ll =	projectInfo.getAtTown();
					String []at = ll.split(", ");
					for(String code:at){
						attown += LabelHelper.getInstance().buildCodeName(4419,code) + "、";
					}
					attown = attown.substring(0,attown.lastIndexOf("、"));
				}
				if(projectInfo.getTechGrade()!= null){
					techgrade = projectInfo.getTechGrade();
				}
				
				if(projectInfo.getSocialLevel()!= null){
					sociallevel = projectInfo.getSocialLevel();
				}
				
				if(projectInfo.getOrgCode().getOrgName()!= null){
					orgName = projectInfo.getOrgCode().getOrgName();
				}
				
				if(projectInfo.getPrincipal()!= null){
					principal = projectInfo.getPrincipal();
				}
				
				if(pp.containsKey("3") && pp.get("3").toString()!= null && !pp.get("3").toString().equals("")){
					supervisorOrg = pp.get("3").toString();
				}
				
				if(pper.containsKey("3") && pper.get("3").toString()!= null && !pper.get("3").toString().equals("")){
					supPrincipal = pper.get("3").toString();
				}
				
				if(pp.containsKey("4") && pp.get("4").toString()!= null && !pp.get("4").toString().equals("")){
					constructOrg = pp.get("4").toString();
				}
				
				if(pper.containsKey("4") && pper.get("4").toString()!= null && !pper.get("4").toString().equals("")){
					conPrincipal = pper.get("4").toString();
				}
				
				
				doc.add(new Field("atTown", attown, Field.Store.YES,
						Field.Index.ANALYZED));
				
				doc.add(new Field("techGrade", techgrade,
						Field.Store.YES, Field.Index.ANALYZED));
				
				doc.add(new Field("socialLevel", sociallevel,
						Field.Store.YES, Field.Index.ANALYZED));
				
				doc.add(new Field("orgName", orgName, 
						Field.Store.YES, Field.Index.ANALYZED));
				
				doc.add(new Field("principal", principal, 
						Field.Store.YES, Field.Index.ANALYZED));
				
				
				doc.add(new Field("supervisorOrg", supervisorOrg, 
						Field.Store.YES, Field.Index.ANALYZED));
				
				doc.add(new Field("supPrincipal", supPrincipal, 
						Field.Store.YES, Field.Index.ANALYZED));
				
				doc.add(new Field("constructOrg", constructOrg, 
							Field.Store.YES, Field.Index.ANALYZED));
				
				doc.add(new Field("conPrincipal", conPrincipal, 
						Field.Store.YES, Field.Index.ANALYZED));
				
				doc.add(new Field("createDate", DateTools.dateToString(
							projectInfo.getCreateDate(), Resolution.MINUTE),
							Field.Store.YES, Field.Index.NOT_ANALYZED));
				iw.addDocument(doc);
			}
			// 自动优化合并索引文件
			iw.optimize();
			iw.close();
			long endTime = new Date().getTime();
			System.out.println("一共" + size + ",这花费了" + (endTime - startTime)
					+ " 毫秒来把文档增加到索引里面去!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List<LuceneProjectModel> SearchByLucene(String index,
			String keyword, String startDate, String endDate) {
		File fsDir = new File(index+"//project");
		Analyzer analyzer = new IKAnalyzer();
		List<LuceneProjectModel> projectList = new ArrayList<LuceneProjectModel>();
		try {
			// 索引查询
			IndexReader reader = IndexReader.open(FSDirectory.open(fsDir), true); // only searching, so
															// read-only=true
			IndexSearcher isearcher = new IndexSearcher(reader);

			BooleanQuery booleanQuery = new BooleanQuery();
			
//			Query query = IKQueryParser.parse("id", keyword);// 分析检索词
//			query1.setBoost(1.0f);
//			booleanQuery.add(query1, Occur.SHOULD);
			
			Query query1 = IKQueryParser.parse("projectName", keyword);// 分析检索词
			query1.setBoost(1.5f);
			booleanQuery.add(query1, Occur.SHOULD);

			Query query2 = IKQueryParser.parse("atTown", keyword);// 分析检索词
			query2.setBoost(1.0f);
			booleanQuery.add(query2, Occur.SHOULD);

			Query query3 = IKQueryParser.parse("orgName", keyword);// 分析检索词
			query3.setBoost(1.0f);
			booleanQuery.add(query3, Occur.SHOULD);
			
			Query query4 = IKQueryParser.parse("supervisorOrg", keyword);// 分析检索词
			query4.setBoost(1.0f);
			booleanQuery.add(query4, Occur.SHOULD);
			
			Query query5 = IKQueryParser.parse("constructOrg", keyword);// 分析检索词
			query5.setBoost(1.0f);
			booleanQuery.add(query5, Occur.SHOULD);
			
			BooleanQuery filterBooleanQuery = new BooleanQuery();
			TermRangeQuery rangeQuery = new TermRangeQuery("createDate",startDate, endDate, true, true);
			filterBooleanQuery.add(rangeQuery, BooleanClause.Occur.MUST);

			// 将booleanQuery封装到Filter中
			Filter filter = new CachingWrapperFilter(new QueryWrapperFilter(
					filterBooleanQuery));

			TopScoreDocCollector collector = TopScoreDocCollector.create(100,
					true);
			//设置相识度
			isearcher.setSimilarity(new IKSimilarity());
			isearcher.search(booleanQuery, filter, collector);

			ScoreDoc[] hits = collector.topDocs(0, 100).scoreDocs;
//			QueryScorer qs = new QueryScorer(query);
			QueryScorer qs1 = new QueryScorer(query1);
			QueryScorer qs2 = new QueryScorer(query2);
			QueryScorer qs3 = new QueryScorer(query3);
			QueryScorer qs4 = new QueryScorer(query4);
			QueryScorer qs5 = new QueryScorer(query5);
			for (ScoreDoc h : hits) {
				Document d = isearcher.doc(h.doc);
				LuceneProjectModel lucene = new LuceneProjectModel();
				String projectName = d.get("projectName");
				String atTown = d.get("atTown");
				String orgName = d.get("orgName");
				String supervisorOrg = d.get("supervisorOrg");
				String constructOrg = d.get("constructOrg");
				lucene.setId(d.get("id"));
				lucene.setTechGrade(d.get("techGrade"));
				lucene.setSocialLevel(d.get("socialLevel"));
				lucene.setPrincipal(d.get("principal"));
				lucene.setSupPrincipal(d.get("supPrincipal"));
				lucene.setConPrincipal(d.get("conPrincipal"));
				
				Formatter formatter = new SimpleHTMLFormatter("<font style='background-color:#F9F400;'>", "</font>");
//				Highlighter h = new Highlighter(formatter, qs);
				Highlighter h1 = new Highlighter(formatter, qs1);
				Highlighter h2 = new Highlighter(formatter, qs2);
				Highlighter h3 = new Highlighter(formatter, qs3);
				Highlighter h4 = new Highlighter(formatter, qs4);
				Highlighter h5 = new Highlighter(formatter, qs5);
				
				String projectName1 = h1.getBestFragment(analyzer, "projectName", projectName);
				String atTown1 = h2.getBestFragment(analyzer, "atTown", atTown);
				String orgName1 = h3.getBestFragment(analyzer, "orgName", orgName);
				String supervisorOrg1 = h4.getBestFragment(analyzer, "supervisorOrg", supervisorOrg);
				String constructOrg1 = h5.getBestFragment(analyzer, "constructOrg", constructOrg);
				if (projectName1 != null) {
					lucene.setProjectName(projectName1);
				} else {
					lucene.setProjectName(projectName);
				}
				if (atTown1 != null) {
					lucene.setAtown(atTown1);
				} else {
					lucene.setAtown(atTown);
				}
				if (orgName1 != null) {
					lucene.setOrgName(orgName1);
				} else {
					lucene.setOrgName(orgName);
				}
				if (supervisorOrg1 != null) {
					lucene.setSupervisorOrg(supervisorOrg1);
				} else {
					lucene.setSupervisorOrg(supervisorOrg);
				}
				if (constructOrg1 != null) {
					lucene.setConstructOrg(constructOrg1);
				} else {
					lucene.setConstructOrg(constructOrg);
				}
//				lucene.setCreateDate(DateUtils.toDate(d.get("createDate")));
				projectList.add(lucene);
			}
			System.out.println("在工程中找到：" + hits.length + " 个");
			isearcher.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
		return projectList;
	}

}
